﻿#include "TollgateScene.h"
#include "TiledMapInfo.h"
#include "Bullet.h"
#include "BulletMoveController.h"
#include "FourDirectionMoveController.h"
#include "cocostudio\CocoStudio.h"
#include "ui\CocosGUI.h"
#include "StartScene2.h"
#include "SimpleAudioEngine.h"
#include "CsvUtil.h"

using namespace cocos2d::ui;

Scene* TollgateScene::createScene(int level){
	auto scene = Scene::create();
	auto layer = TollgateScene::create(level);
	scene->addChild(layer);
	return scene;
}

TollgateScene* TollgateScene::create(int level){
	auto tollgate = new TollgateScene();
	
	if (tollgate && tollgate->init(level)){
		tollgate->autorelease();
	}
	else{
		CC_SAFE_DELETE(tollgate);
	}
	return tollgate;
}

bool TollgateScene::init(int level){
	if (!Layer::init()){
		return false;
	}
	m_musicNum = 1;
	status = RUNNING;
	for (int i = 1; i <= 10; i++){
		CocosDenshion::SimpleAudioEngine::getInstance()->preloadEffect(StringUtils::format("music/fire%d.mp3", i).c_str());
	}

	this->scheduleUpdate();
	isMouseDown = false;
	m_level = level;
	m_time = 0;
	this->setSwallowsTouches(false);
	Size visibleSize = Director::getInstance()->getVisibleSize();

	std::string path = StringUtils::format("maps/map%d.tmx", m_level);
	auto map = TiledMapInfo::createMapInfoWithFile(path.c_str());
	map->getTiledMap()->setTag(10);
	this->addChild(map->getTiledMap());
	addPlayer(map->getTiledMap());
	
	m_enemyManager = EnemyManager::createWithLevel(m_level);
	
	m_enemyManager->setTiledMap(map->getTiledMap());
	map->getTiledMap()->addChild(m_enemyManager, 9);
	
	m_status = (CSLoader::createNode("Status.csb"));
	this->addChild(m_status, 11);
	auto UI = (Widget*)m_status;
	
	auto levelText = (Text*)Helper::seekWidgetByName(UI, StringUtils::format("TextL%d", m_level));
	levelText->setVisible(true);

		this->schedule(schedule_selector(TollgateScene::timeCounter), 1.0f);
		auto textD = (Text*)Helper::seekWidgetByName(UI, "TextD");
		auto timeText = (Text*)Helper::seekWidgetByName(UI, "TextTime");
		textD->setVisible(false);
		timeText->setVisible(true);

	m_bulletManager = BulletManager::create();
	map->getTiledMap()->addChild(m_bulletManager);
	m_bulletManager->bindEnemyManager(m_enemyManager);
	m_bulletManager->bindPlayer(m_player);

	setNotification();
	bindListener();
	return true;
}

void TollgateScene::addBullet(Entity* entity, Vec2 pos, bool isPlayer, int atk, int bul){
	if (status == WIN || status == LOSE) return;
	auto bullet = Bullet::createWithNum(bul, 1,entity->getTankHead() , pos);
	bullet->setIsPlayer(isPlayer);
	bullet->setTiledMap((TMXTiledMap*)(this->getChildByTag(10)));
	bullet->setAtk(atk);
	auto bulletController = BulletMoveController::create();
	bullet->setController(bulletController);
	this->addChild(bulletController);
	m_bulletManager->addChild(bullet);
	if (isPlayer){
		CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(StringUtils::format("music/fire%d.mp3", m_musicNum).c_str());
		m_musicNum++;
		if (m_musicNum > 10){
			m_musicNum = 1;
		}
	}
}

void TollgateScene::addPlayer(TMXTiledMap* map){
	Player::delPlayer();
	TMXObjectGroup* objGroup = map->getObjectGroup("objects");

	ValueMap playerPointMap = objGroup->getObject("PlayerPoint");
	float playerX = playerPointMap.at("x").asFloat();
	float playerY = playerPointMap.at("y").asFloat();
	auto num = CsvUtil::getInstance()->getInt(1, 1, "Tollgate/Player.csv");
	auto hp = CsvUtil::getInstance()->getInt(1, 2, "Tollgate/Player.csv");
	auto atk = CsvUtil::getInstance()->getInt(1, 3, "Tollgate/Player.csv");
	auto speed = CsvUtil::getInstance()->getInt(1, 4, "Tollgate/Player.csv");
	auto bullet = CsvUtil::getInstance()->getInt(1, 5, "Tollgate/Player.csv");
	m_player = Player::create(Tank::createWithNum(num));
	m_player->setAtk(atk);
	m_player->setHP(hp);
	m_player->setTiledMap(map);
	m_player->setSpeed(speed);
	m_player->setBullet(bullet);
	m_player->setMaxHP(hp);
	map->addChild(m_player, 10);
	
	auto moveController = FourDirectionMoveController::create();
	this->addChild(moveController);

	m_player->setController(moveController);
	m_player->setTagPosition(playerX, playerY);

}

void TollgateScene::bindListener(){
	Layer::onEnter();
	auto listener = EventListenerMouse::create();

	listener->onMouseDown = [this](Event* event){
		isMouseDown = true;
		this->schedule(schedule_selector(TollgateScene::playerFire), 0.1f);
	};

	listener->onMouseMove = [this](Event* event){
		auto e = (EventMouse*)event;
		auto ePos = Vec2(e->getCursorX(), e->getCursorY());
		auto pos = m_player->getParent()->convertToWorldSpaceAR(m_player->getPosition());
		auto l = sqrt(pow(ePos.x - pos.x, 2) + pow(ePos.y - pos.y, 2));
		float rotation = 0;
		if (l != 0){
			if (ePos.x - pos.x >= 0 && ePos.y - pos.y >= 0){
				rotation = 90 - CC_RADIANS_TO_DEGREES(asin(abs((ePos.y - pos.y) / l)));
			}
			if (ePos.x - pos.x >= 0 && ePos.y - pos.y < 0){
				rotation = 90 + CC_RADIANS_TO_DEGREES(asin(abs((ePos.y - pos.y) / l)));
			}
			if (ePos.x - pos.x < 0 && ePos.y - pos.y < 0){
				rotation = 270 - CC_RADIANS_TO_DEGREES(asin(abs((ePos.y - pos.y) / l)));
			}
			if (ePos.x - pos.x < 0 && ePos.y - pos.y >= 0){
				rotation = 270 + CC_RADIANS_TO_DEGREES(asin(abs((ePos.y - pos.y) / l)));
			}
		}
		m_player->setTankHead(rotation);

	};

	listener->onMouseUp = [this](Event* event){
		isMouseDown = false;
		this->unschedule(schedule_selector(TollgateScene::playerFire));
	};
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

}

void  TollgateScene::update(float dt){
	auto UI = (Widget*)m_status;
	auto hp = (LoadingBar*)Helper::seekWidgetByName(UI, "HpBar");
	CCLOG("HP = %d %d", m_player->getHP(), m_player->getMaxHP());
	hp->setPercent(m_player->getHP() * 1.0 / m_player->getMaxHP() * 100);
	auto textHp = (Text*)Helper::seekWidgetByName(UI, "TextHP");
	textHp->setText(StringUtils::format("%d%%", (int)(m_player->getHP() * 1.0 / m_player->getMaxHP() * 100)));
}

void TollgateScene::playerFire(float dt){
	addBullet(m_player, m_player->getTagPosition(), true, m_player->getAtk(), m_player->getBullet());
}

void TollgateScene::setNotification(){
	NotificationCenter::getInstance()->addObserver(this, callfuncO_selector(TollgateScene::win), "win", NULL);
	NotificationCenter::getInstance()->addObserver(this, callfuncO_selector(TollgateScene::lose), "lose", NULL);
}

void TollgateScene::removeNotification(){
	NotificationCenter::getInstance()->removeAllObservers(this);
}

void TollgateScene::win(Ref*){
	status = WIN;
	this->unscheduleAllSelectors();
	_eventDispatcher->removeEventListenersForType(EventListener::Type::MOUSE);
	if (m_level != 3){
		auto win = CSLoader::createNode("CompleteLayer.csb");
		auto UI = (Widget*)win;
		
		auto menu = (Button*)Helper::seekWidgetByName(UI, "MenuBtn");
		menu->addTouchEventListener(this, toucheventselector(TollgateScene::onClickBackBtn));

		auto next = (Button*)Helper::seekWidgetByName(UI, "NextBtn");
		next->addTouchEventListener(this, toucheventselector(TollgateScene::onClickNextBtn));

		this->addChild(win, 12);
	}
	else{
		auto win = CSLoader::createNode("FinishLayer.csb");
		auto UI = (Widget*)win;

		auto menu = (Button*)Helper::seekWidgetByName(UI, "Menu3Btn");
		menu->addTouchEventListener(this, toucheventselector(TollgateScene::onClickBackBtn));

		this->addChild(win, 12);
	}
	CCLOG("win");
}

void TollgateScene::lose(Ref*){
	status = LOSE;
	this->unscheduleAllSelectors();
	auto lose = CSLoader::createNode("FailLayer.csb");
	auto UI = (Widget*)lose;
	//_eventDispatcher->removeEventListenersForType(EventListener::Type::MOUSE);
	auto replay = (Button*)Helper::seekWidgetByName(UI, "ReplayBtn");
	replay->addTouchEventListener(this, toucheventselector(TollgateScene::onClickReplayBtn));
	auto menu = (Button*)Helper::seekWidgetByName(UI, "Menu2Btn");
	menu->addTouchEventListener(this, toucheventselector(TollgateScene::onClickBackBtn));
	this->addChild(lose, 12);
	CCLOG("lose");
}


void TollgateScene::onClickNextBtn(Ref*, TouchEventType type){
	switch (type)
	{
	case TouchEventType::TOUCH_EVENT_ENDED:
			srand(time(NULL));
			this->removeAllChildrenWithCleanup(true);
			
			this->removeNotification();
			Director::getInstance()->replaceScene(TollgateScene::createScene(m_level+1));
		break;
	default:
		break;
	}
}

void TollgateScene::onClickReplayBtn(Ref*, TouchEventType type){
	switch (type)
	{
	case TouchEventType::TOUCH_EVENT_ENDED:
			srand(time(NULL));
			this->removeAllChildrenWithCleanup(true);
			init(m_level);
		break;
	default:
		break;
	}
}
void TollgateScene::onClickBackBtn(Ref*, TouchEventType type){
	switch (type)
	{
	case TouchEventType::TOUCH_EVENT_ENDED:
		srand(time(NULL));
		this->removeAllChildrenWithCleanup(true);
		this->unscheduleUpdate();
		this->removeNotification();
		Director::getInstance()->replaceScene(StartScene2::createScene());
		break;
	default:
		break;
	}
}

void TollgateScene::timeCounter(float dt){
	auto UI = (Widget*)m_status;
	m_time += dt;
	auto timeText = (Text*)Helper::seekWidgetByName(UI, "TextTime");
	timeText->setText(StringUtils::format("%02d:%02d", ((int)m_time) % 3600 / 60, ((int)m_time) % 3600 % 60));
}